﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using FxCopContrib.TestHarness;

namespace FxCopContrib.Tests
{
    /// <summary>
    /// Summary description for DoNotUseParseAndToStringToConvertTypes
    /// </summary>
    [TestClass]
    public class DoNotUseParseAndToStringToConvertTypesTests
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        [TestMethod]
        public void RuleShouldDetectDirectParseToString()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            int i = int.Parse(1.ToString());
                        }
                    "
                )
                .WithReferencesTo(typeof(int), typeof(string))
                .WillFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldDetectDirectParseStringEmptyConcat()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            int i = int.Parse(string.Empty + 1);
                        }
                    "
                )
                .WithReferencesTo(typeof(int), typeof(string))
                .WillFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldDetectDirectParseQuoteQuoteConcat()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            int i = int.Parse("""" + 1);
                        }
                    "
                )
                .WithReferencesTo(typeof(int), typeof(string))
                .WillFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldDetectLocalTostringParse()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            string value = 1.ToString();
                            int i = int.Parse(value);
                        }
                    "
                )
                .WithReferencesTo(typeof(int), typeof(string))
                .WillFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldDetectLocalStringEmptyAppendParse()
        {
            var rule = new DoNotUseParseAndToStringToConvertTypes();

            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            string value = string.Empty + 1;
                            int i = int.Parse(value);
                        }
                    "
                )
                .WithReferencesTo(typeof(int), typeof(string))
                .WillFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldDetectLocalQuoteQuoteConcatParse()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            string value = """" + 1;
                            int i = int.Parse(value);
                        }
                    "
                )
                .WithReferencesTo(typeof(int), typeof(string))
                .WillFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldDetectLocalDirectConvertToString()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            int i = Convert.ToInt32(1.ToString());
                        }
                    "
                )
                .WithReferencesTo(typeof(Convert), typeof(string))
                .WillFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldNotTriggerOnNormalConvert()
        {
            FxCopTest.ForRule<DoNotUseParseAndToStringToConvertTypes>().OnMethod(
                @"
                    public void TestMethod()
                    {
                        int i = Convert.ToInt32(1f);
                    }
                "
                )
                .WithReferencesTo(typeof(Convert), typeof(string))
                .WillNotFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldNotTriggerOnNormalParse()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            int i = int.Parse(""1"");
                        }
                    "
                )
                .WithReferencesTo(typeof(Convert), typeof(string))
                .WillNotFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldNotTriggerOnNormalTryParse()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            int i = -1;
                            int.TryParse(""1"", out i);
                        }
                    "
                )
                .WithReferencesTo(typeof(Convert), typeof(string))
                .WillNotFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }

        [TestMethod]
        public void RuleShouldDetectLocalDirectTryParseToString()
        {
            FxCopTest
                .ForRule<DoNotUseParseAndToStringToConvertTypes>()
                .OnMethod(
                    @"
                        public void TestMethod()
                        {
                            int i = -1;
                            int.TryParse(1.ToString(), out i);
                        }
                    "
                )
                .WithReferencesTo(typeof(int), typeof(string))
                .WillFind(ProblemPrototype.Default)
                .Conclusive()
                .Verify();
        }
    }
}
